package xuegao.study.mall.rbac.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import xuegao.study.mall.common.api.CommonResult;
import xuegao.study.mall.common.domain.UserDto;
import xuegao.study.mall.common.dto.rbac.UmsAdminRegisterDto;
import xuegao.study.mall.common.model.ums.UmsAdmin;
import xuegao.study.mall.common.model.ums.UmsAdminRoleRelation;
import xuegao.study.mall.common.model.ums.UmsMenu;
import xuegao.study.mall.common.model.ums.UmsRole;
import xuegao.study.mall.rbac.config.SpringUtil;
import xuegao.study.mall.rbac.service.UmsAdminCacheService;
import xuegao.study.mall.rbac.service.UmsAdminService;
import xuegao.study.mall.rbac.service.UmsMenuService;
import xuegao.study.mall.repo.dao.ums.UmsAdminDao;
import xuegao.study.mall.repo.dao.ums.UmsRoleDao;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class UmsAdminServiceImpl implements UmsAdminService {

    @Autowired
    private UmsAdminDao umsAdminDao;

    @Autowired
    private UmsRoleDao umsRoleDao;

    @Autowired
    private UmsMenuService umsMenuService;

    @Override
    public int register(UmsAdminRegisterDto registerDto) {
        UmsAdmin umsAdmin = new UmsAdmin();
        BeanUtils.copyProperties(registerDto, umsAdmin);
        umsAdmin.setCreateTime(new Date());
        // 创建bcrypt密码编码器
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encodePass = passwordEncoder.encode(umsAdmin.getPassword());
        umsAdmin.setPassword(encodePass);
        int count = umsAdminDao.insertAdmin(umsAdmin);
        getCacheService().setAdmin(umsAdmin);
        return count;
    }

    @Override
    public int deleteById(Long id) {
        getCacheService().delAdmin(id);
        return umsAdminDao.deleteById(id);
    }

    @Override
    public int updateAdminStatus(Long adminId, Integer status) {
        getCacheService().delAdmin(adminId);
        UmsAdmin admin = new UmsAdmin();
        admin.setId(adminId);
        admin.setStatus(status);
        return umsAdminDao.updateAdmin(admin);
    }

    @Override
    public int updateAdmin(Long id, UmsAdmin admin) {
        getCacheService().delAdmin(id);
        admin.setId(id);
        return umsAdminDao.updateAdmin(admin);
    }

    @Override
    public CommonResult getAdminInfo(String userStr) {
        UserDto userDto = JSONUtil.toBean(userStr, UserDto.class);
        UmsAdmin userAdmin = umsAdminDao.selectById(userDto.getId());
        Map<String, Object> data = new HashMap<>();
        data.put("username", userAdmin.getUsername());
        data.put("icon", userAdmin.getIcon());
        List<UmsMenu> menus = umsMenuService.getMenuListByAdminId(userAdmin.getId());
        data.put("menus", menus);
        List<UmsRole> roleList = umsRoleDao.selectByAdminId(userAdmin.getId());
        if (CollUtil.isNotEmpty(roleList)) {
            List<String> roles = roleList.stream().map(UmsRole::getName).collect(Collectors.toList());
            data.put("roles", roles);
        }
        return CommonResult.success(data);
    }

    @Override
    public List<UmsAdmin> selectList(Integer pageNum, Integer pageSize, String name) {
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.hasText(name)) {
            params.put("name", name);
        }
        PageHelper.startPage(pageNum, pageSize);
        return umsAdminDao.selectList(params);
    }

    @Override
    public List<UmsRole> adminRoles(Long adminId) {
        return umsRoleDao.selectByAdminId(adminId);
    }

    @Override
    public int allocRoles(Long adminId, List<Long> roleIds) {
        // 1.删除关联关系
        int count = umsAdminDao.deleteAdminRoleRelationByAdminId(adminId);
        // 2.重新保存关联关系
        if (!CollectionUtils.isEmpty(roleIds)) {
            List<UmsAdminRoleRelation> list = new ArrayList<>();
            for (Long roleId : roleIds) {
                UmsAdminRoleRelation relation = new UmsAdminRoleRelation();
                relation.setAdminId(adminId);
                relation.setRoleId(roleId);
                list.add(relation);
            }
            return umsAdminDao.batchInsertUmsAdminRoleRelation(list);
        }
        return count;
    }

    @Override
    public UserDto getUserByUsername(String username) {
        UmsAdmin admin = getAdminByUsername(username);
        if (admin != null) {
            List<UmsRole> roleList = umsRoleDao.selectByAdminId(admin.getId());
            UserDto userDto = new UserDto();
            BeanUtils.copyProperties(admin, userDto);
            if (roleList != null && roleList.size() > 0) {
                List<String> roleStrList = roleList.stream().map(item -> item.getId() + "_" + item.getName()).collect(Collectors.toList());
                userDto.setRoles(roleStrList);
            }
            return userDto;
        }
        return null;
    }

    @Override
    public UmsAdmin getAdminByUsername(String username) {
        UmsAdmin admin = null;
        // 先从缓存中获取数据
        admin = getCacheService().getAdmin(username);
        if (admin != null) {
            return admin;
        }
        admin = umsAdminDao.getAdminByUsername(username);
        if (admin != null) {
            getCacheService().setAdmin(admin);
        }
        return admin;
    }

    public UmsAdminCacheService getCacheService() {
        return SpringUtil.getBean(UmsAdminCacheService.class);
    }
}
